<?
  require("Util.php");
  
  $stat = wikifyFile();
  echo $stat;
  
	/*
		Holding the information of a file
	*/
	class FileText {
		public $str, $counter, $name;
		
		public function __construct($str, $counter) {
			$this->name = "";
    	$this->str = $str;//text inside the section
    	$this->counter = $counter;//the page count
  	}
		
		public function __toString() {
			$tst = "file:".$this->name."<br />\n";
			$tst .= "counter:".$this->counter."<br />\n";
			$tst .= "data:".$this->str."<br />\n";
			$tst .= "=====<br />\n";
			return $tst;
		}
	}
	/*
		Holding the information of a section
	*/
	class Item {
		public $str, $level, $counter, $parenti, $child;
  
  		public function __construct($str, $level, $counter, $parent, $child) {
    		$this->str = $str;//text inside the section
    		$this->level = $level;//the section level
    		$this->counter = $counter;//the page count
			  $this->parenti = $parent;//section parent
			  $this->child = $child;//subsections
  		}
		
		//add text to the section
		public function appendText ($str) {
			$this->str .= $str;
			$count = strlen($str);
			$this->counter += $count;
		}
		
		//get text belong to this section and its subsections
		public function getText() {
			$tst = $this->str;
			for ($i = 0; $i < count($this->child); $i++) {
				$tst .= " ".$this->child[$i]->getText();
			}
			return $tst;
		}
		
		//printing the item properties and childs
		private function printSectionArray ($tab) {
			$tst = $tab."str:".$this->str."<br />\n"; 
			$tst .= $tab."level:".$this->level."<br />\n";
			$tst .= $tab."length:".strlen($this->str)."<br />\n";
			//$this->setCounter();
			//$this->counter = $this->getCounter();
			$tst .= $tab."counter:".$this->counter."<br />\n"; 
			for ($i = 0; $i < count($this->child); $i++) {
				$tst .= $this->child[$i]->printSectionArray($tab."----");
			}
			$tst .= "=====<br />\n";
			return $tst;
		}
		
		public function __toString() {
			return ($this->printSectionArray(""));
		}
	}
	
	/*
		Splitting text for the wikification and combine them once
		it has been wikified
	*/
	 function wikifyFile () {
	   $folder_name = $_POST["templateFile"];
	   $folderpath = $GLOBALS['uploaddir']."/".$folder_name;
	   $input_file = $folderpath."/".$GLOBALS["wikibook"];//path for the wikified file
	   
	   echo "splitting text <br />"; 
	   $curr_files = splitFile($input_file);
	   echo "wikifying splitted text <br />"; 
	   wikifySubFiles($folderpath,$input_file,$curr_files);
	  // echo "tidying text <br />";  
	   //tidyText($folderpath, $input_file);
	   return "&msg=Building index, definition and synonym tables&result=no error";
	 }
	 
	 /*
	   Split the file to be wikified into smaller files
	   @param string $input_file  the path to the input XHTML file
	 */
	 function splitFile ($input_file) {
		 $str = file_get_contents($input_file);
		 //parse the text so we know what are the text inside each section tag
		 echo "parsing headers<br />";
		 $curr_section = parseHeader($str);
		 //now we need to split it as big as possible for wikification
		 $curr_files = array();
		 $new_file = new FileText("", 0);
		 array_push($curr_files, $new_file);
		 echo "splitting headers<br />";
		 $curr_files = splitHeadersToFile($curr_section, $curr_files);
		 return $curr_files;
   }
   
	 /*
	   Wikified each sub-files and combine them into a single file again
	   @param string $folder_name the path to the book directory
	   @param string $input_file  the path to the input XHTML file
	   @param array  $curr_files  the list of subfiles
	 */
	 function wikifySubFiles($folder_name,$input_file,$curr_files) {
	    $fname = explode(".",basename($input_file));
  		$j = 1;
  		//for each file do the wikification
  		$str = "";
  		for ($i = 0; $i < count($curr_files); $i++) {
  			if ($curr_files[$i]->counter > 0) {
  				$curr_files[$i]->name = $folder_name."/".$fname[0]."_Page_".$j.".htm";//the name of the file
  				echo "save sub-file ".$j." counter ".$curr_files[$i]->counter." with the name ".$curr_files[$i]->name."<br />";
  				$fh = modifyFile($curr_files[$i]->name, 'w') or die("can't open file");
  				fwrite($fh, $curr_files[$i]->str);
  				fclose($fh);
				/*$tname = $folder_name."/old_".$fname[0]."_Page_".$j.".htm";
				$fh = modifyFile($tname, 'w') or die("can't open file");
  				fwrite($fh, $curr_files[$i]->str);
  				fclose($fh);*/
  				$j++;
  				
  				//do the wikification
  				echo "get wiki definition<br />";
  				getWikiDefintion($folder_name, $curr_files[$i]->name);
  					
  				//get the file content
  				$new_data = file_get_contents($curr_files[$i]->name);
  				$str .= $new_data;
  				
  				//and delete the file
  				unlink($curr_files[$i]->name);
  			}
  		}
  		//combine the file together again
  		$fh = modifyFile($input_file, 'w') or die("can't open file");
  		fwrite($fh, $str);
  		fclose($fh);
	 }
	 
	/*
		Do wikification
		@param string $folder_name the path to the book directory
		@param string $input_file the path to the input XHTML file
	*/
	function getWikiDefintion($folder_name, $input_file) {$stime = microtime(); $time1 = now($stime);
		$data = file_get_contents($input_file);
		$postdata = http_build_query(
			array(
				"source" => $data
			)
		);
			
		$opts = array("http" =>
			array(
				"method" => "POST",
				"header" => "Content-type: application/x-www-form-urlencoded",
				"content" => $postdata
			)
		);
		
		$context = stream_context_create($opts);
		
		$wiki_opts = $GLOBALS["wikiaddr"]."task=wikify&wrapInXml=false&sourceMode=3";
		$wiki_opts .= "&minProbability=0.5&repeatMode=0&wikiLinkFormat=2";
		$new_data = file_get_contents($wiki_opts, false, $context);
		
		$fh = modifyFile($input_file, 'w') or die("can't open file");
		fwrite($fh, $new_data);
		fclose($fh); echo "finish get wiki link<br />"; $time2 = now($stime);timeLog("getWikiDefinition", $time2-$time1);
	}
	
	/*
	 	Splitting the given text to smaller text of max N characters
		while making sure that we don't split inside an html tag
		@param string $str the text to be spit
		@param number $num the max number of characters
	*/
	function substrHTML($str, $num) {
		$split_str = array();
		array_push($split_str, "");
		$chars = preg_split('/(<[\/]?[^>]+>)/i', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
		for ($i = 0; $i < count($chars); $i++) {
			if (preg_match('/(<[\/]?[^>]+>)/i', $chars[$i]) == true) {//html tag
				$lc = strlen($split_str[count($split_str) - 1]);
				if (($lc == 0) || (strlen($chars[$i]) <= ($num - $lc))) {//the whole tag fit
					$split_str[count($split_str) - 1] .= $chars[$i];
				} else {
					array_push($split_str, $chars[$i]);
				}
			} else {//any other string
				$tst = $chars[$i];
				$tchars = preg_split('/(\s+)/i',$tst, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
				for ($k = 0; $k < count($tchars); $k++) {
					$lc = strlen($split_str[count($split_str) - 1]);
					if (($lc == 0) || (strlen($tchars[$k]) <= ($num - $lc))) {//the whole str fit
						$split_str[count($split_str) - 1] .= $tchars[$k];
					} else {
						array_push($split_str, $tchars[$k]);
					}
				}
			}
		}
		
		return $split_str;
	}
	 
	 /*
	 	Splitting into sub-files based on the section so that in each file
		there's max 100,000 chars.
		@param Item $curr_section the section
		@param Array $curr_files the list of subfiels
	 */
	function splitHeadersToFile($curr_section, $curr_files) {
		$max_count = $GLOBALS["maxchars"];
		
		$elem = $curr_files[count($curr_files) - 1];
		if ($curr_section->counter <= ($max_count - $elem->counter)) {
			//the whole section and subsection fit
			$elem->str .= $curr_section->getText();
			$elem->counter += $curr_section->counter;
		} else {
			//can't fit the whole section so create a new file
			$new_file = new FileText("", 0);
			array_push($curr_files, $new_file);
			
			//split this section text
			$tst = $curr_section->str;
			if (strlen($tst) > 0) {
				$sub_tst = substrHTML($tst, $max_count);
				for ($i = 0; $i < count($sub_tst); $i++) {
					if (strlen($sub_tst[$i]) > 0) {
						if ($i > 0) {
							$new_file = new FileText("", 0);
							array_push($curr_files, $new_file);
						}
						$new_file->str .= $sub_tst[$i];
						$new_file->counter += strlen($sub_tst[$i]);
					}
				}
			}
			
			//get the subsection
			for ($i = 0; $i < count($curr_section->child); $i++) {
				$curr_files = splitHeadersToFile($curr_section->child[$i], $curr_files);
			}	
		}
		
		return $curr_files;
	}
	 
	/*
    Get the counter of text in this section and its subsection
    @param Item $curr_section the current section
  */
	function setCounter($curr_section) {
		for ($i = 0; $i < count($curr_section->child); $i++) {
			$curr_section->counter += setCounter($curr_section->child[$i]);
		}
		
		return $curr_section->counter;
	}
	
	/*
		Parsing the specified string so we know what are the text inside each section tag
		@param string $str the string
	*/
	function parseHeader($str) { 
    $tag = "section";
		$chars = preg_split('/(<'.$tag.'[^>]*>)/i', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
		$curr_section = new Item("",0,0,array(),array());
		$head = $curr_section;
		for ($i = 0; $i < count($chars); $i++) {
			if (preg_match("/<".$tag."[>|\s]/i",$chars[$i]) == true) {//match <section>
				$new_section = new Item($chars[$i],$curr_section->level + 1, 
										strlen($chars[$i]), $curr_section, array());
				array_push($curr_section->child, $new_section);
				if (stripos($chars[$i], " />") === false) {
					$curr_section = $new_section;
				}
			} else {
				$echars = preg_split('/(<\/'.$tag.'>)/i', $chars[$i], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
				for ($j = 0; $j < count($echars); $j++) {
					if (stripos($echars[$j], "</".$tag.">") !== false) {//match </section>
						$curr_section->appendText($echars[$j]);
						$curr_section = $curr_section->parenti;
					} else {
						$hchars = preg_split('/(<[\/]?h[0-9][^>]*>)/i', $echars[$j],  -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
						for ($hi = 0; $hi < count($hchars); $hi++) {
							if (preg_match('/<h[0-9][>|\s]/i',$hchars[$hi]) == true) {//match <hN>
								$hlevel = (int)substr($hchars[$hi], 2, 1); 
								while (($curr_section->level > 0) && 
									   ($curr_section->level >= $hlevel)) {
									$curr_section = $curr_section->parenti;
								}
								$new_section = new Item($hchars[$hi],$curr_section->level + 1, 
														strlen($hchars[$hi]), $curr_section, array());
								array_push($curr_section->child, $new_section);
								$curr_section = $new_section;
							} else {//match everything else
								$curr_section->appendText($hchars[$hi]);
							}
						}
					}
				}
			}
		}
		setCounter($head);
		
		return $head;
	}
	
	
?>